import router from '@/router'
import appStore from '@/store'
import dataSources from '@/api'
import plugins from './plugins'
import log from './utils/log'
import cmlpanel from '@/assets/js/app/cmlpanel'
import cmlGlobal from '@/assets/js/app/cmlpanel/util/cmlGlobal'

import { default as panelServer } from '@/assets/js/app/cmlpanel/panelServer'
import * as anov from 'anov-core'
import defaultConfig from '@/assets/js/app/config'
import * as fullScreen from '../common/fullScreen'
import { msg, notice, modal } from '../../../assets/js/app/message'
import mergewith from 'lodash.mergewith'
import { util } from 'dtc'
import { getStoredData, deepFreeze } from './utils/tools.js'

const ENV = process.env.NODE_ENV
let __begTime = new Date(),
  _initTimes = 0
const app = {
  isInit: false,
  cmlpanel, //控制面板
  panelServer,
  plugins, //系统插件
  defaultConfig,
  modal,
  msg,
  notice,
  log,
  ...anov.runtimeServer.getEventBus(),
  ...anov, //可视化服务引擎
  ...cmlGlobal,
  ...fullScreen, //全屏控制
  init(opt) {
    opt = opt || { config: {} }
    //配置优先级: defaultConfig <- storedConfig <- chipConfig <- runtimeConfig & token
    // save default config copy
    if (!window.anovDefaultConfig) {
      let defCfig = util.cloneDeep(defaultConfig)
      delete defCfig.license
      delete defCfig.panel.permission
      window.anovDefaultConfig = deepFreeze(defCfig)
    }
    // get stored config
    const lsn = `${this.projectId}_${this.platformVersion.replace(/\./g, '-')}`
    let storedConfig = getStoredData(lsn)
    if (ENV === 'development') {
      // 开发环境特殊处理数据源
      // 不对数据源做持久化处理
      let optDataSource = opt.config.dataSource || {},
        storedDataSource = storedConfig.dataSource,
        defaultDataSource = this.defaultConfig.dataSource || {}
      storedDataSource &&
        (storedDataSource.type = optDataSource.type || defaultDataSource.type)
    }
    let { loadTimes } = storedConfig
    // merge configs
    this.config = this.defaultConfig = mergewith(
      util.cloneDeep(this.defaultConfig),
      loadTimes === 0 && _initTimes === 0 ? {} : storedConfig,
      opt.config,
      (objVal, srcVal, key) => {
        if (key === 'themes' && !srcVal.length) {
          return undefined
        }
        if (Array.isArray(objVal)) {
          return srcVal
        }
      }
    )
    _initTimes++
    this.config.debug = this.devMode
    let root = this.root ? Object.assign(this.root, this) : null
    let config = this.config
    //路由事件注册
    opt.__reload ||
      root.$router.beforeEach((to, from, next) => {
        app.$emit('pageLeave', { to, from, next })
      })
    opt.__reload ||
      root.$router.beforeResolve((to, from, next) => {
        app.$emit('pageEnter', { to, from, next })
      })
    //运行时服务
    this.runtimeServer.init(config)
    opt.__reload || this.runtimeServer.setCurrentContext(root)
    //预加载
    this.preloadServer.init(config)
    //事件总线
    this.eventBus = this.runtimeServer.getEventBus()

    //授权服务
    this.licenseServer.init(config)
    opt.__reload ||
      this.licenseServer.addEventListener('noPass', e => {
        console.log(e)
        app.modal.open({
          type: 'error',
          componentsName: 'validPeriod',
          content: '无效的许可证'
        })
      })
    //系统环境
    opt.__reload || this.envServer.init(config)
    //数据源服务
    this.dataSourceServer.init(config)
    // 页面服务
    this.pageServer.init(config)
    // 基础组件服务
    this.partServer.init(config)
    // 音效服务
    opt.__reload || this.soundServer.init(config.soundServer)
    // 动画服务
    this.animateServer.init(config.animateConfig)
    //动作服务
    this.actionServer.init(config)
    opt.__reload || this.actionServer.addActions(config.actions)
    //语音合成服务
    opt.__reload || this.voiceFeedbackServer.init(config)
    //语音识别服务
    this.voiceRecognizeServer.init(config)
    opt.__reload || this.voiceRecognizeServer.addCommands(config.commands)
    //人脸识别服务
    this.faceRecognizeServer.init(config)
    //手势识别
    this.gestureRecognizeServer.init(config)
    //快捷键服务
    this.hotkeyServer.init(config)
    opt.__reload || this.hotkeyServer.addHotkeys(config.hotkeys)
    // 控制面板
    this.panelServer.init(config.panel)
    // 光感服务
    this.lightSensorServer.init(config)

    //主题服务
    this.themeServer.init(config.theme)
    // i18n
    this.languageServer.init(config.language)

    // 系统自检
    this.systemCheckServer.init(config)

    // this.preloadServer.addEventListener('process',(e)=>{
    //   console.log(e.result.name+'加载完成，完成百分比:'+e.result.completeCount/e.result.allCount*100+'%')
    // })
    // this.preloadServer.addEventListener('completed',(e)=>{
    //   console.log('全部资源加载完成')
    // })
  },
  //配置比较
  compareConfig(oldConfig, newConfig) {
    let _ = app.root
    let str = ''
    newConfig.panel.permission.map(newItem => {
      let isFind = oldConfig.panel.permission.find(oldItem => {
        return newItem == oldItem
      })
      str +=
        _.$t(app.chipServer.configI18nMapping[newItem]) +
        ':' +
        (!isFind ? _.$t('chip.newAuthorization') : _.$t('chip.authorized')) +
        '<br>'
    })

    return str
  }
}
//运行时服务设置
app.runtimeServer.setAppStore(appStore)
app.runtimeServer.setCurrentContext({ $router: router, ...anov })
app.pageServer.create(router)
//数据服务

app.dataSourceServer.addDataSources(dataSources)
app.api = app.dataSourceServer.create()
try {
  app.api &&
    app.api.init &&
    setTimeout(() => {
      app.$on('init', () => {
        let path = app.runtimeServer.getCurrentContext().$route.path
        app.api.init(path)
      })
    }, 0)
} catch (e) {
  app.dataSourceServer.addError('init datasource error,' + e.message)
}
//数据芯片服务设置
app.chipServer.init()
app.chipServer.addEventListener('configLoad', chipConfig => {
  app.init({ config: chipConfig.result, __reload: true })
  if (chipConfig.isDropLoad) {
    let msg = app.compareConfig(app.config, chipConfig.result)
    app.modal.open({
      componentsName: 'chipLoad',
      content: msg,
      style: { width: '600px', height: '600px' }
    })
  } else {
    setTimeout(() => {
      app.$emit('init')
    }, 0)
    app.isInit = true
    app.log('app加载时间' + (new Date() - __begTime) + 'ms')
  }
  app.log('数据芯片初始化完成,' + chipConfig.msg)
})
app.chipServer.addEventListener('error', e => {
  help(e.result)
})
app.chipServer.addEventListener('notValid', e => {
  help(e.result)
})

export default app
